#include "clib_stack_netif.h"

#define     PKT_MIN_NUMS(a,b) (a) > (b) ? (b) : (a)

/**
 * 设置hw参数回调函数
 * @param netif     hw操作相关指针
 * @param opt       hw操作函数
 * @param args      hw回调操作函数
 * @return
 *   - 0    成功
 *   - -1   失败
 */
i32_t 
clib_netif_opt_set(stack_netif_t* netif, netif_opt_t *opt, void *args)
{
    netif->opts = opt;
    netif->args = args;
    return rn_ok;
}

/**
 * 向hw写入数据包
 * @param netif     hw操作相关指针
 * @param pkt       待写入相关的数据包指针
 * @param nums      待写入相关的数据包数量
 * @param dir       数据包方向
 * @return
 *   - 0    成功
 *   - -1   失败
 */
i32_t 
clib_netif_packet_put(stack_netif_t* netif, void** pkt, i32_t nums,clib_pkt_dir_t dir)
{
    int ret = 0;
    if(dir == CLIB_PKT_DIR_SEND) {
        ret = PKT_MIN_NUMS(NETIF_PKT_MAX - netif->send_max, nums);
        memcpy(&netif->send[netif->send_max], pkt, sizeof(void*) * ret);
        netif->send_max += ret;
    } else {
        ret = PKT_MIN_NUMS(NETIF_PKT_MAX - netif->recv_max, nums);
        memcpy(&netif->recv[netif->recv_max], pkt, sizeof(void*) * ret);
        netif->recv_max += ret;
    }
    return ret;
}

/**
 * 向hw获取数据包
 * @param netif     hw操作相关指针
 * @param pkt       待获取相关的数据包指针cache
 * @param nums      待获取相关的数据包最大数量
 * @param dir       数据包方向
 * @return          获取的数据包数量
 */
i32_t 
clib_netif_packet_get(stack_netif_t* netif, void** pkt, i32_t nums, clib_pkt_dir_t dir)
{
    i32_t ret = 0;
    if(dir == CLIB_PKT_DIR_SEND) {
        ret = PKT_MIN_NUMS(netif->send_max - netif->send_idx,nums);
        memcpy(pkt, &netif->send[netif->send_idx], sizeof(void*) * ret);
        netif->send_idx += ret;

        if(netif->send_idx == netif->send_max) {
            netif->send_idx = 0;
            netif->send_max = 0;
        } else {
            /** TODO 内存重叠***/
            memcpy(netif->send, &netif->send[netif->send_idx], sizeof(void*) * (netif->send_max - netif->send_idx));
            netif->send_max -= netif->send_idx;
            netif->send_idx = 0;
        }
    } else {
        ret = PKT_MIN_NUMS(netif->recv_max - netif->recv_idx, nums);
        memcpy(pkt, &netif->recv[netif->recv_idx], sizeof(void*) * ret);
        netif->recv_idx += ret;

        if(netif->recv_idx == netif->recv_max) {
            netif->recv_idx = 0;
            netif->recv_max = 0;
        } else {
            /** TODO 内存重叠***/
            memcpy(netif->recv, &netif->recv[netif->recv_idx], sizeof(void*) * (netif->recv_max - netif->recv_idx));
            netif->recv_max -= netif->recv_idx;
            netif->recv_idx = 0;
        }
    }
    return ret;
}

/**
 * 向hw申请数据包
 * @param netif     hw操作相关指针
 * @param pkt       待获取申请的数据包指针
 * @return 
 * - 0  成功
 * - -1 失败
 */
i32_t 
clib_netif_packet_malloc(stack_netif_t* netif, void** pkt)
{
    return netif->opts->netif_pkt_malloc(netif->args, pkt);
}

/**
 * 向hw释放数据包
 * @param netif     hw操作相关指针
 * @param pkt       待释放的数据包
 * @return
 */
void 
clib_netif_packet_free(stack_netif_t* netif, void* pkt)
{
    netif->opts->netif_pkt_free(netif->args, pkt);
}